package com.yfs.cloud.plugin;

import java.sql.Connection;
import java.util.Properties;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

@Intercepts({
		@Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
public class MyPlugin implements Interceptor {

	private long time;

	// 方法拦截
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		// 通过StatementHandler获取执行的sql
		StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
		BoundSql boundSql = statementHandler.getBoundSql();
		String sql = boundSql.getSql();
		// sql语句为: SELECT id,create_time,modify_time,creator,modifier,deleted,version,username,password,sex,phone,openid,wx_nickname,wx_avatar  FROM tb_users  WHERE  username = ?
		System.out.println("sql语句为: " + sql);
		// 动态的改变一下sql运行的参数：以前1号员工，实际从数据库查询3号员工
		Object target = invocation.getTarget();
		// 当前拦截到的对象：org.apache.ibatis.executor.statement.RoutingStatementHandler@604c909
		System.out.println("当前拦截到的对象：" + target);
		// 拿到target的元数据
		MetaObject metaObject = SystemMetaObject.forObject(target);
		Object value = metaObject.getValue("parameterHandler.parameterObject");
		// sql语句用的参数是：com.yfs.cloud.entity.User@2a27eb75
		System.out.println("sql语句用的参数是：" + value);
		// 修改完sql语句要用的参数
		// metaObject.setValue("parameterHandler.parameterObject", 11);
		long start = System.currentTimeMillis();
		Object proceed = invocation.proceed();
		long end = System.currentTimeMillis();
		if ((end - start) > time) {
			System.out.println("本次数据库操作是慢查询，sql是:" + sql);
		}
		return proceed;
	}

	// 获取到拦截的对象，底层也是通过代理实现的，实际上是拿到一个目标代理对象
	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	// 获取设置的阈值等参数
	@Override
	public void setProperties(Properties properties) {
		this.time = Long.parseLong(properties.getProperty("time"));
	}
}
